/*
 * Log.cpp
 *
 *  Created on:  May 29, 2009
 *      Author:  Zach Riggle A37627537
 *      Project: CSE410 Project 1
 */

#include "Log.h"

Log::Level Log::outputLevel = DEFAULT_LEVEL;

Log _debug(Log::DEBUG);
Log _info(Log::INFO);
Log _warn(Log::WARN);
Log _error(Log::ERROR);
Log _critical(Log::CRITICAL);
char *stoplog = new char;

Log::Log(Level l) {
    level = l;
}

Log::~Log() {

}

void Log::setLevel(Level l) {
    outputLevel = l;
}

string Log::getLevelName(Level level) {
    switch (level) {
    case DEBUG:
        return "DEBUG";
    case INFO:
        return "INFO";
    case WARN:
        return "WARN";
    case ERROR:
        return "ERROR";
    case CRITICAL:
        return "CRITICAL";
    }
    return "! Name Not Defined !";
}

string Log::getPrefix(Level l) {
    stringstream ss;
    ss << getpid() << " - " << getLevelName(l) << ": ";
    return ss.str();
}
string Log::getPrefix() {
    return Log::getPrefix(level);
}

string Log::getPostfix(string fn, string file, int line) {
    stringstream ss;
    ss << " [" << fn << " on " << file << ":" << line << "]";
    return ss.str();
}

Log& Log::operator<<(const string& x) {
    if (level >= outputLevel)
        currentLine << x;
    return *this;
}
Log& Log::operator<<(const char* x) {
    if (level >= outputLevel) {

        if (x == stoplog) {
            if (level < ERROR)
                cout << currentLine.str() << endl;
            else
                cerr << currentLine.str() << endl;
            currentLine.str("");
        } else {
            currentLine << x;
        }
    }

    return *this;
}
Log& Log::operator<<(const int& x) {
    if (level >= outputLevel)
        currentLine << x;
    return *this;
}
Log& Log::operator<<(const char& x) {
    if (level >= outputLevel)
        currentLine << x;
    return *this;
}
Log& Log::operator<<(const float& x) {
    if (level >= outputLevel)
        currentLine << x;
    return *this;
}

//void Log::log(Level level, const char* fn, const char* file, int line, string msg) {
//	if (level < Log::outputLevel)
//		return;
//
//	cout << getPrefix(level) << msg << getPostfix(fn,file,line) << endl;
//}
//
//void Log::log(Level level, const char* fn, const char* file, int line, ostringstream msg) {
//	if (level < Log::outputLevel)
//		return;
//
//	cout << getPrefix(level) << msg.str() <<  " [" << fn << " on " << file << ":" << line << "]" << endl;
//}

string Log::getDate() {
    int bufSize = 32;
    char *buffer = new char[bufSize];
    time_t curr;
    time(&curr); // get current time_t value


    strftime(buffer, bufSize, "%Y-%m-%dT%H:%M:%S%z", localtime(&curr));
    return string(buffer);
}

/*
 * #define DEFAULT_LEVEL Level.DEBUG

 class Log {
 public:
 Log();
 virtual ~Log();

 enum Level { DEBUG, INFO, WARN, ERROR, CRITICAL };
 static void log(Level level, string fn, string file, string line, string msg);
 static void log(Level level, string fn, string file, string line, ostringstream msg);
 static void setLevel(Level newLevel);

 protected:
 static Level level;
 };
 */
